home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / XMSLIBR1.ARJ / XMSLIB.PAS < prev    next >
Pascal/Delphi Source File  |  1991-08-11  |  21KB  |  580 lines

  1. (******************************************************************************
  2. *                                   xmsLib                                    *
  3. ******************************************************************************)
  4. unit xmsLib;
  5.  
  6. interface
  7.  
  8. uses
  9.     dos
  10.     ;
  11. type
  12.    xmsMovePtr = ^xmsMoveStructure;
  13.    xmsMoveStructure = record
  14.       length         : longint; { 32-bit # of bytes to transfer }
  15.       sourceHandle   : word;
  16.       sourceOffset   : longint;
  17.       destHandle     : word;
  18.       destOffset     : longint;
  19.    end; { xmsMoveStructure definition }
  20. var
  21.    xmsPresent   : boolean; { true if XMS was detected }
  22.    xmsAddress   : pointer; { used to point to XMS entry address }
  23.    xmsVersion   : word;
  24.    xmmVersion   : word;
  25.    hmaPresent   : boolean;
  26.    xmsErrorCode : byte; { if an error exists, it will be placed here }
  27.  
  28. procedure detectXMS; { look for xms existance, and sets global library variables }
  29. procedure setXMSHandlerAddress;
  30. procedure getXMSVersionNumber;
  31. function  printXMSVersion : string; { a readable string .. }
  32. function  printXMMVersion : string; { a readable string .. }
  33. function  requestHMA : boolean;
  34. function  releaseHMA : boolean;
  35. function globalEnableA20 : boolean;
  36. function globalDisableA20 : boolean; 
  37. function localEnableA20 : boolean;
  38. function localDisableA20 : boolean;
  39. function queryA20 : boolean;
  40. procedure queryFreeExtendedMemory(var largestBlock, totalInK : word);
  41. function xmsLargestBlock : word;
  42. function xmsTotalFreeMemory : word;
  43. function allocateXMB(sizeInK : word; var handle : word) : boolean;
  44. function freeXMB(handle : word) : boolean;
  45. function moveXMB(structure : xmsMovePtr) : boolean;
  46. function moveXMBlock(len : longint; srcHandle : word; srcOfs : longint;
  47.                      dstHandle : word; dstOfs : longint) : boolean;
  48. function mainstgToXMB(len : word; fromPtr : pointer; 
  49.                       toHandle : word; toOfs : longint) : boolean;
  50. function XMBtoMainstg(len : word; toPtr : pointer;
  51.                       fmHandle : word; fmOfs : longint) : boolean;
  52. function lockXMB(handle : word) : boolean;
  53. function unlockXMB(handle : word) : boolean;
  54. function getXMBInformation(handle : word; var lockCount, freeHandles : byte;
  55.                            var sizeInK : word) : boolean;
  56. function reallocXMB(newSizeInK, handle : word) : boolean;
  57. function requestUMB(sizeInParagraphs : word; var segmentOfUMB : word;
  58.                     var sizeAllocatedOrAvailable : word) : boolean;
  59. function releaseUMB(segmentOfUMB : word) : boolean;
  60. function xmsErrorStr : string;
  61.  
  62. implementation
  63. type
  64.    xmsErrorType = record
  65.       errorNumber  : byte;
  66.       errorMessage : string;
  67.    end;
  68. const
  69.    maxXMSErrors = 27;
  70.    xmsErrorArray : array [1 .. maxXMSErrors] of xmsErrorType = (
  71.       (errorNumber : $80; errorMessage :  'Function not implemented'),
  72.       (errorNumber : $81; errorMessage :  'VDISK device detected'),
  73.       (errorNumber : $82; errorMessage :  'A20 Error occured'),
  74.       (errorNumber : $8e; errorMessage :  'General driver error'),
  75.       (errorNumber : $8f; errorMessage :  'Fatal driver error'),
  76.       (errorNumber : $90; errorMessage :  'HMA does not exist'),
  77.       (errorNumber : $91; errorMessage :  'HMA is already in use'),
  78.       (errorNumber : $92; errorMessage :  'Size is smaller then /HMAMIN= parameter'),
  79.       (errorNumber : $93; errorMessage :  'HMA not allocated'),
  80.       (errorNumber : $94; errorMessage :  'A20 line still enabled'),
  81.       (errorNumber : $a0; errorMessage :  'No more free extended memory'),
  82.       (errorNumber : $a1; errorMessage :  'No more XMS handles'),
  83.       (errorNumber : $a2; errorMessage :  'Invalid handle'),
  84.       (errorNumber : $a3; errorMessage :  'Invalid source handle'),
  85.       (errorNumber : $a4; errorMessage :  'Invalid source offset'),
  86.       (errorNumber : $a5; errorMessage :  'Invalid destination handle'),
  87.       (errorNumber : $a6; errorMessage :  'Invalid destination offset'),
  88.       (errorNumber : $a7; errorMessage :  'Invalid length'),
  89.       (errorNumber : $a8; errorMessage :  'Move resulted in overlap'),
  90.       (errorNumber : $a9; errorMessage :  'Parity error'),
  91.       (errorNumber : $aa; errorMessage :  'Block not locked'),
  92.       (errorNumber : $ab; errorMessage :  'Block locked'),
  93.       (errorNumber : $ac; errorMessage :  'Block lock count overflow'),
  94.       (errorNumber : $ad; errorMessage :  'Lock failure'),
  95.       (errorNumber : $b0; errorMessage :  'Smaller UMB available'),
  96.       (errorNumber : $b1; errorMessage :  'No UMBs available'),
  97.       (errorNumber : $b2; errorMessage :  'Invalid UMB segment number')
  98.       );
  99. var
  100.    regs : registers;
  101.  
  102. (******************************************************************************
  103. *                                  detectXMS                                  *
  104. ******************************************************************************)
  105. procedure detectXMS;
  106. begin
  107.      asm
  108.         mov xmsPresent, 0 { no xms available }
  109.         mov ax, $4300
  110.         int $2f { multiplexer interrupt identification }
  111.         cmp al, $80 { well , is there XMM ? }
  112.         jne @noXMSDriver
  113.         mov xmsPresent, 1 { true, we have an xms driver }
  114. @noXMSDriver:
  115.      end; { asm }
  116. end; {detectXMS}
  117.  
  118. (******************************************************************************
  119. *                            setXMSHandlerAddress                             *
  120. ******************************************************************************)
  121. procedure setXMSHandlerAddress;
  122. begin
  123.      asm
  124.         mov ax,$4310
  125.         int $2f { ES:BX points to xms driver entry point }
  126.         mov word ptr [xmsAddress], bx
  127.         mov word ptr [xmsAddress + 2], es
  128.      end; { asm }
  129. end; {setXMSHandlerAddress}
  130.  
  131. (******************************************************************************
  132. *                             getXMSVersionNumber                             *
  133. ******************************************************************************)
  134. procedure getXMSVersionNumber;
  135. begin
  136.      asm
  137.         xor ah, ah; { function 0 .. }
  138.         call [xmsAddress]
  139.         mov xmsVersion, ax
  140.         mov xmmVersion, bx
  141.         mov byte ptr hmaPresent, dl { true or false .. }
  142.      end; { asm }
  143. end; {getXMSVersionNumber}
  144.  
  145. (******************************************************************************
  146. *                               printXMSVersion                               *
  147. ******************************************************************************)
  148. function printXMSVersion;
  149. var
  150.    s1, s2  : string;
  151. begin
  152.    str(xmsVersion div $100, s1);
  153.    str(xmsVersion mod $100, s2);
  154.    printXMSVersion := s1 + '.' + s2;
  155. end; {printXMSVersion}
  156.  
  157. (******************************************************************************
  158. *                               printXMMVersion                               *
  159. ******************************************************************************)
  160. function printXMMVersion;
  161. var
  162.    s1, s2, s3  : string;
  163. begin
  164.    str(XMMVersion div $100, s1);
  165.    str((XMMVersion mod $100) div $10, s2);
  166.    str(XMMVersion mod $10, s3);
  167.    printXMMVersion := s1 + '.'+ s2 + s3;
  168. end; {printXMMVersion}
  169.  
  170. (******************************************************************************
  171. *                                 requestHMA                                  *
  172. ******************************************************************************)
  173. function requestHMA;
  174. var
  175.    requestGranted : boolean;
  176. begin
  177.      asm
  178.         mov ah, 1
  179.         mov dx, $ffff { assume we are not tsr, but an application }
  180.         call [xmsAddress]
  181.         mov requestGranted, al
  182.         mov xmsErrorCode, bl
  183.      end; { asm }
  184.      requestHMA := requestGranted; { if not, check xmsErrorCode }
  185. end; {requestHMA}
  186.  
  187. (******************************************************************************
  188. *                                 releaseHMA                                  *
  189. ******************************************************************************)
  190. function releaseHMA;
  191. var
  192.    releaseGranted : boolean;
  193. begin
  194.      asm
  195.         mov ah, 2
  196.         call [xmsAddress]
  197.         mov releaseGranted, al
  198.         mov xmsErrorCode, bl
  199.      end; {asm}
  200.      releaseHMA := releaseGranted;
  201. end; {releaseHMA}
  202.  
  203. (******************************************************************************
  204. *                              globalEnableA20                                *
  205. ******************************************************************************)
  206. function globalEnableA20;
  207. var
  208.    A20geGranted : boolean;
  209. begin
  210.    asm
  211.       mov ah, 3
  212.       call [xmsAddress]
  213.       mov A20geGranted, al
  214.       mov xmsErrorCode, bl
  215.    end; { asm }
  216.    globalEnableA20 := a20geGranted;
  217. end; {globalEnableA20}
  218.  
  219. (******************************************************************************
  220. *                              globalDisableA20                               *
  221. ******************************************************************************)
  222. function globalDisableA20;
  223. var
  224.    A20gdGranted : boolean;
  225. begin
  226.    asm
  227.       mov ah, 4
  228.       call [xmsAddress]
  229.       mov A20gdGranted, al
  230.       mov xmsErrorCode, bl
  231.    end; { asm }
  232.    globalDisableA20 := a20gdGranted;
  233. end; {globalDisableA20}
  234.  
  235. (******************************************************************************
  236. *                              localEnableA20                                 *
  237. ******************************************************************************)
  238. function localEnableA20;
  239. var
  240.    A20geGranted : boolean;
  241. begin
  242.    asm
  243.       mov ah, 5
  244.       call [xmsAddress]
  245.       mov A20geGranted, al
  246.       mov xmsErrorCode, bl
  247.    end; { asm }
  248.    localEnableA20 := a20geGranted;
  249. end; {localEnableA20}
  250.  
  251. (******************************************************************************
  252. *                              localDisableA20                                *
  253. ******************************************************************************)
  254. function localDisableA20;
  255. var
  256.    A20gdGranted : boolean;
  257. begin
  258.    asm
  259.       mov ah, 6
  260.       call [xmsAddress]
  261.       mov A20gdGranted, al
  262.       mov xmsErrorCode, bl
  263.    end; { asm }
  264.    localDisableA20 := a20gdGranted;
  265. end; {localDisableA20}
  266.  
  267. (******************************************************************************
  268. *                                  queryA20                                   *
  269. * Returns True if A20 is physically enabled. query validity of respons by     *
  270. * looking at the xmsErrorCode first !                                         *
  271. * i.e. ...                                                                    *
  272. * findA20State := queryA20;                                                   *
  273. * if (xmsErrorCode <> 0) then                                                 *
  274. *     Error                                                                   *
  275. * else findA20State has the proper value according to the A20 state           *
  276. ******************************************************************************)
  277. function queryA20;
  278. var
  279.    A20State : boolean;
  280. begin
  281.    asm
  282.       mov ah, 7
  283.       call [xmsAddress]
  284.       mov A20State, al
  285.       mov xmsErrorCode, bl
  286.    end; { asm }
  287.    queryA20 := A20State;
  288. end; {queryA20}
  289.  
  290. (******************************************************************************
  291. *                           queryFreeExtendedMemory                           *
  292. ******************************************************************************)
  293. procedure queryFreeExtendedMemory;
  294. var
  295.    ourLB, ourTIK : word;
  296. begin
  297.    asm
  298.       mov ah, 8
  299.       call [xmsAddress]
  300.       mov ourLB, ax
  301.       mov ourTIK, dx
  302.       mov xmsErrorCode, bl
  303.    end; { asm }
  304.    largestBlock := ourLB;
  305.    totalInK := ourTIK;
  306. end; {queryFreeExtendedMemory}
  307.  
  308. (******************************************************************************
  309. *                               xmsLargestBlock                               *
  310. ******************************************************************************)
  311. function xmsLargestBlock;
  312. var
  313.    lb, tik : word;
  314. begin
  315.    queryFreeExtendedMemory(lb, tik);
  316.    xmsLargestBlock := lb;
  317. end; {xmsLargestBlock}
  318.  
  319. (******************************************************************************
  320. *                             xmsTotalFreeMemory                              *
  321. ******************************************************************************)
  322. function xmsTotalFreeMemory;
  323. var
  324.    lb, tik : word;
  325. begin
  326.    queryFreeExtendedMemory(lb, tik);
  327.    xmsTotalFreeMemory := tik;
  328. end; {xmsTotalFreeMemory}
  329.  
  330. (******************************************************************************
  331. *                                 allocateXMB                                 *
  332. * if returns True handle has the handle to the memory block                   *
  333. ******************************************************************************)
  334. function allocateXMB;
  335. var
  336.    allocGranted : boolean;
  337.    ourHandle    : word;
  338. begin
  339.    asm
  340.       mov ah, 9
  341.       mov dx, sizeInK
  342.       call [xmsAddress]
  343.       mov allocGranted, al { did we make it ? }
  344.       mov ourHandle, dx 
  345.       mov xmsErrorCode, bl
  346.    end; { asm }
  347.    allocateXMB := allocGranted;
  348.    if (allocGranted) then
  349.       handle := ourHandle;
  350. end; {allocateXMB}
  351.  
  352. (******************************************************************************
  353. *                                   freeXMB                                   *
  354. ******************************************************************************)
  355. function freeXMB;
  356. var
  357.    releaseGranted : boolean;
  358. begin
  359.    asm
  360.       mov ah, $a
  361.       mov dx, handle
  362.       call [xmsAddress]
  363.       mov releaseGranted, al
  364.       mov xmsErrorCode, bl
  365.    end; { asm }
  366.    freeXMB := releaseGranted;
  367. end; {freeXMB}
  368.  
  369. (******************************************************************************
  370. *                                   moveXMB                                   *
  371. ******************************************************************************)
  372. function moveXMB;
  373. var
  374.    moveGranted : boolean;
  375.    segmento    : word;
  376.    offseto     : word;
  377. begin
  378.    segmento := seg(structure^);
  379.    offseto  := ofs(structure^);
  380.    asm
  381.       push ds
  382.       pop es
  383.       mov si, offseto
  384.       mov ax, segmento
  385.       mov ds, ax
  386.       mov ah, $b
  387.       call [es:xmsAddress]
  388.       push es
  389.       pop ds
  390.       mov moveGranted, al
  391.       mov xmsErrorCode, bl
  392.    end; { asm }
  393.    moveXMB := moveGranted;
  394. end; {moveXMB}
  395.  
  396. (******************************************************************************
  397. *                                 moveXMBlock                                 *
  398. ******************************************************************************)
  399. function moveXMBlock;
  400. var
  401.    struct : xmsMoveStructure;
  402. begin
  403.    with struct do begin
  404.       length := len;
  405.       sourceHandle := srcHandle;
  406.       sourceOffset := srcOfs;
  407.       destHandle := dstHandle;
  408.       destOffset := dstOfs;
  409.    end; { with }
  410.    moveXMBlock := moveXMB(@struct); { go do it ! }
  411. end; {moveXMBlock}
  412.  
  413. (******************************************************************************
  414. *                                mainstgToXMB                                 *
  415. * move fm ptr len bytes to XMB handle, at offset                              *
  416. ******************************************************************************)
  417. function mainstgToXMB;
  418. var
  419.    l : longint;
  420. begin
  421.    l := longint(fromPtr);
  422.    mainstgToXMB := moveXMBlock(len, 0, l, toHandle, toOfs);
  423. end; {mainstgToXMB}
  424.  
  425. (******************************************************************************
  426. *                                XMBtoMainstg                                 *
  427. * xmb fmhandle at ofsset fmofs, move to main storage at pointer toptr, len byt*
  428. ******************************************************************************)
  429. function XMBtoMainstg;
  430. var
  431.    l : longint;
  432. begin
  433.    l := longint(toPtr);
  434.    XMBtoMainstg := moveXMBlock(len, fmHandle, fmOfs, 0, l);
  435. end; {XMBtoMainstg}
  436.  
  437. (******************************************************************************
  438. *                                   lockXMB                                   *
  439. ******************************************************************************)
  440. function lockXMB;
  441. var
  442.    lockGranted : boolean;
  443. begin
  444.    asm
  445.       mov ah, $c
  446.       mov dx, handle
  447.       call [xmsAddress]
  448.       mov lockGranted, al
  449.       mov xmsErrorCode, bl
  450.    end; { asm }
  451.    lockXMB := lockGranted;
  452. end; {lockXMB}
  453.  
  454. (******************************************************************************
  455. *                                  unlockXMB                                  *
  456. ******************************************************************************)
  457. function unlockXMB;
  458. var
  459.    unlockGranted : boolean;
  460. begin
  461.    asm
  462.       mov ah, $d
  463.       mov dx, handle
  464.       call [xmsAddress]
  465.       mov unlockGranted, al
  466.       mov xmsErrorCode, bl
  467.    end; { asm }
  468.    unlockXMB := unlockGranted;
  469. end; {unlockXMB}
  470.  
  471. (******************************************************************************
  472. *                              getXMBInformation                              *
  473. ******************************************************************************)
  474. function getXMBInformation;
  475. var
  476.    informationReceived : boolean; 
  477.    ourSIK              : word;
  478.    ourFH, ourLC        : byte;
  479. begin
  480.    asm
  481.       mov ah, $e
  482.       mov dx, handle
  483.       call [xmsAddress]
  484.       mov informationReceived, al
  485.       mov ourLC, bh
  486.       mov ourFH, bl
  487.       mov ourSIK, dx
  488.       mov xmsErrorCode, bl
  489.    end; { asm }
  490.    getXMBInformation := informationReceived;
  491.    sizeInK := ourSIK;
  492.    freeHandles := ourFH;
  493.    lockCount := ourLC;
  494. end; {getXMBInformation}
  495.  
  496. (******************************************************************************
  497. *                                 reallocXMB                                  *
  498. ******************************************************************************)
  499. function reallocXMB;
  500. var
  501.    reallocGranted : boolean;
  502. begin
  503.    asm
  504.       mov ah, $f
  505.       mov bx, newSizeInK
  506.       mov dx, handle
  507.       call [xmsAddress]
  508.       mov reallocGranted, al
  509.       mov xmsErrorCode, bl
  510.    end; { asm }
  511.    reallocXMB := reallocGranted;
  512. end; {reallocXMB}
  513.  
  514. (******************************************************************************
  515. *                                 requestUMB                                  *
  516. ******************************************************************************)
  517. function requestUMB;
  518. var
  519.    requestGranted : boolean;
  520.    ourSOUMB, ourSAOA : word;
  521. begin
  522.    asm
  523.       mov ah, $10
  524.       mov dx, sizeInParagraphs
  525.       call [xmsAddress]
  526.       mov requestGranted, al
  527.       mov ourSOUMB, bx
  528.       mov ourSAOA, dx
  529.       mov xmsErrorCode, bl
  530.    end; { asm }
  531.    requestUMB := requestGranted;
  532.    segmentOfUMB := ourSOUMB;
  533.    sizeAllocatedOrAvailable := ourSAOA;
  534. end; {requestUMB}
  535.  
  536. (******************************************************************************
  537. *                                 releaseUMB                                  *
  538. ******************************************************************************)
  539. function releaseUMB;
  540. var
  541.    releaseGranted : boolean;
  542. begin
  543.    asm
  544.       mov ah, $11
  545.       mov dx, segmentOfUMB
  546.       call [xmsAddress]
  547.       mov releaseGranted, al
  548.       mov xmsErrorCode, bl
  549.    end; { asm }
  550.    releaseUMB := releaseGranted;
  551. end; {releaseUMB}
  552.  
  553. (******************************************************************************
  554. *                                 xmsErrorStr                                 *
  555. ******************************************************************************)
  556. function xmsErrorStr;
  557. var
  558.    i, errorFound : byte;
  559. begin
  560.    errorFound := 0;
  561.    for i := 1 to maxXMSErrors do
  562.       if (xmsErrorCode = xmsErrorArray[i].errorNumber) then
  563.          errorFound := i;
  564.    if (errorFound = 0) then
  565.       xmsErrorStr := 'Unknown XMS error'
  566.    else
  567.       xmsErrorStr := xmsErrorArray[errorFound].errorMessage;
  568. end; {xmsErrorStr}
  569.  
  570. (******************************************************************************
  571. *                                    MAIN                                     *
  572. ******************************************************************************)
  573. begin
  574.    detectXMS;
  575.    if (xmsPresent) then begin
  576.       setXMSHandlerAddress;
  577.       getXMSVersionNumber;
  578.    end;
  579. end.
  580.